﻿using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Collections.Generic;
using System.ComponentModel;

namespace TA.Turbo.Controls
{
	public enum HttpVerb
	{
		Get = 0, Post = 1
	}
	public enum PostMode
	{
		Ajax = 0, Page = 1
	}
	/// <summary>
	/// Summary description for PostScenario
	/// </summary>
	public class PostScenario : BaseControlReferenceGroup
	{
		public PostScenario()
		{

			HttpVerb = HttpVerb.Post;
			PostMode = PostMode.Ajax;
			CausesValidation = true;
		}
		#region PROPS
		/// <summary>
		/// Page-wide unique ID of this scenario.
		/// </summary>
		public string Id { get; set; }
		/// <summary>
		/// The URL of the page to post (action). Defaults to current page.
		/// </summary>
		public string PostUrl { get; set; }
		/// <summary>
		/// HTTP verb.
		/// </summary>
		public HttpVerb HttpVerb { get; set; }
		/// <summary>
		/// Post mode.
		/// </summary>
		public PostMode PostMode { get; set; }
		/// <summary>
		/// Comma-separated list of validation groups (for designer).
		/// </summary>
		public string ValidationGroups
		{
			get
			{
				return _validationGroups.Value;
			}
			set
			{
				_validationGroups.Value = value;
			}
		}
		/// <summary>
		/// List of validation groups (for code behind).
		/// </summary>
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public List<string> ValidationGroupList
		{
			get
			{
				return _validationGroups.ValueList;
			}
		}
		/// <summary>
		/// Causes validation to be performed on the page.
		/// </summary>
		public bool CausesValidation { get; set; }
		/// <summary>
		/// True to strip the hidden fields from the post; false otherwise. Usually used with GET.
		/// </summary>
		public bool Clean { get; set; }
		/// <summary>
		/// Client script function/block executed before sending AJAX request.
		/// </summary>
		public string OnClientPosting { get; set; }
		/// <summary>
		/// Client script function/block executed after AJAX request sent.
		/// </summary>
		public string OnClientPosted { get; set; }
		/// <summary>
		/// Client script function/block executed after AJAX response received.
		/// </summary>
		public string OnClientResponse { get; set; }
		/// <summary>
		/// Client script function/block executed after AJAX request errored out.
		/// </summary>
		public string OnClientError { get; set; }
		/// <summary>
		/// Hidden property that stores IDs of all progress controls which should be activated when this scenario posts.
		/// </summary>
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		[EditorBrowsable(EditorBrowsableState.Never)]
		[Browsable(false)]
		public string[] ProgressControls { get; set; }

		public string Groups
		{
			get
			{
				return _controlReferenceGroups.Value;
			}
			set
			{
				_controlReferenceGroups.Value = value;
			}
		}
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		[Browsable(false)]
		public List<string> GroupList
		{
			get
			{
				return _controlReferenceGroups.ValueList;
			}
		}
		#endregion
		#region INTERNAL
		internal ScenarioCollection _collection;
		internal override Control NamingPoint
		{
			get
			{
				return _collection.NamingPoint;
			}
		}
		MultiPartValue _validationGroups = new MultiPartValue();
		MultiPartValue _controlReferenceGroups = new MultiPartValue();
		/// <summary>
		/// Copy the contents over but resolve the IDs to client IDs.
		/// </summary>
		/// <returns></returns>
		internal PostScenario PrepareForClient()
		{
			PostScenario res = (PostScenario)this.MemberwiseClone();
			res._postControls = new ControlReferenceCollection(res);
			res._returnControls = new ControlReferenceCollection(res);

			PrepareForClient_Controls(this.PostControls, res.PostControls);
			PrepareForClient_Controls(this.ReturnControls, res.ReturnControls);
			return res;
		}
		void PrepareForClient_Controls(List<ControlReference> source, List<ControlReference> dest)
		{
			Func<ControlReference, IEnumerable<ControlReference>> k = this.PrepareForClient_Controls_Children;

			dest.Clear();
			dest.AddRange(source
				.Where(c => c.Control is BaseValueControl)
				.Select(delegate(ControlReference c)
				{
					ControlReference r = (ControlReference)c.Clone();
					r.ControlId = c.Control.ClientID;
					return r;
				}).Concat(source
				.Where(c => !(c.Control is BaseValueControl))
				.SelectMany(k)));
		}
		IEnumerable<ControlReference> PrepareForClient_Controls_Children(ControlReference oneControl)
		{
			List<ControlReference> res = new List<ControlReference>();

			if (oneControl.AnyProperties)
			{
				ControlReference self = (ControlReference)oneControl.Clone();
				self.ControlId = oneControl.Control.ClientID;
				res.Add(self);
			}
			if (oneControl.Value)
			{
				oneControl.Control.ForEachRecursive<BaseValueControl>(delegate(BaseValueControl valueControl)
				{
					ControlReference oneRef = new ControlReference();
					oneRef.ControlId = valueControl.ClientID;
					res.Add(oneRef);
				});
			}
			return res;
		}
		#endregion
	}
}